package com.weiz.task;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 首先需要在配置类上添加 @EnableScheduling
 * 1.`SchedulingConfigurer`简介
 *    - `SchedulingConfigurer`是Spring框架中用于自定义任务调度配置的接口。它提供了一种灵活的方式来配置定时任务，允许开发者通过代码的方式设置任务的执行时间、执行周期等参数，而不是依赖于传统的基于注解（如`@Scheduled`）的固定配置。
 * 2.实现`SchedulingConfigurer`接口触发定时任务的步骤
 *    步骤一：创建任务逻辑类
 *      - 首先，创建一个包含定时任务逻辑的类。这个类可以是一个简单的Java类，其中的方法将作为定时任务被执行。例如：
 *    步骤二：实现`SchedulingConfigurer`接口的配置类
 *      - 创建一个实现`SchedulingConfigurer`接口的配置类。在这个配置类中，重写`configureTasks`方法来设置定时任务的执行计划。例如：
 *      - 在上述配置类中：
 *        - 首先通过构造函数注入了`MyTask`类的实例，这样就可以在配置定时任务时调用`MyTask`中的方法。
 *        - 然后在`configureTasks`方法中，使用`addTriggerTask`方法添加了一个定时任务。`addTriggerTask`方法接受两个参数：
 *          - 第一个参数是一个`Runnable`类型的任务，这里使用Lambda表达式`() -> myTask.doTask()`来指定要执行的任务，即调用`MyTask`类中的`doTask`方法。
 *          - 第二个参数是一个`Trigger`类型的函数，用于确定任务的下一次执行时间。这里使用`CronTrigger`来根据Cron表达式确定下一次执行时间。Cron表达式`0 * * * * *`表示每分钟执行一次任务，你可以根据实际需求修改这个表达式来调整任务的执行周期。
 * 3.工作原理
 *    - 当Spring应用程序启动时，它会扫描并加载所有的配置类。由于`TaskSchedulerConfig`类实现了`SchedulingConfigurer`接口并且被标记为`@Configuration`，Spring会识别这个类并调用`configureTasks`方法。
 *    - 在`configureTasks`方法中设置的定时任务会被添加到Spring的任务调度器中。任务调度器会根据`Trigger`（这里是`CronTrigger`）提供的触发机制来决定何时执行任务。每次任务执行完成后，调度器会再次根据`Trigger`计算下一次任务执行的时间，以此类推，实现定时任务的循环执行。
 */

//spring.task.scheduling.pool.size=10

@Configuration
//@Component
public class TaskSchedulerConfig implements SchedulingConfigurer {
    private static final Logger logger = LoggerFactory.getLogger(TaskSchedulerConfig.class);
    private final MyTask myTask;
    public TaskSchedulerConfig(MyTask myTask) {
        this.myTask = myTask;
    }
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        logger.info("开始配置定时任务...");
        taskRegistrar.addTriggerTask(
                // 要执行的任务
                () -> myTask.doTask(),
                // 任务执行的触发器，这里使用Cron表达式来触发任务
                triggerContext -> {
                    // Cron表达式，这里设置为每分钟执行一次，你可以根据需要修改
                    String cronExpression = "0 * * * * *";
                    //5s
                    cronExpression = "0/5 * * * * *";
                    logger.info("使用Cron表达式: {}", cronExpression);
                    return new CronTrigger(cronExpression).nextExecutionTime(triggerContext);
                }
        );
        logger.info("定时任务配置完成");
    }
}